package com.toocms.jinjuhang.dialog.specification

import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.RelativeSizeSpan
import android.text.style.StyleSpan
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
import com.blankj.utilcode.util.StringUtils
import com.toocms.jinjuhang.BR
import com.toocms.jinjuhang.R
import com.toocms.jinjuhang.config.Constants
import com.toocms.jinjuhang.config.Urls
import com.toocms.jinjuhang.config.UserRepository
import com.toocms.jinjuhang.data.goods.GetSkuData
import com.toocms.jinjuhang.data.goods.GetSpecGoodsAttrData
import com.toocms.jinjuhang.widget.view_model.requestData
import com.toocms.tab.binding.ItemBinding
import com.toocms.tab.binding.command.BindingAction
import com.toocms.tab.binding.command.BindingCommand
import java.lang.StringBuilder

class SpecificationModel(val fragmentDialog: SpecificationDialog) {
    var _stock: Int = 0
    val stock: Int
        get() = _stock
    var _minPer: Int = 0
    val minPer
        get() = _minPer
    var _maxPer: Int = 0
    val maxPer: Int
        get() = _maxPer
    val quantityObservableInt = ObservableInt(1)
    var selectedAttrIds: Array<String?>? = null
    var selectedAttrNames: Array<String?>? = null

    val iconObservableField = ObservableField<String>()
    val nameObservableField = ObservableField<String>()
    val priceObservableField = ObservableField<CharSequence>()

    val attrItems = ObservableArrayList<SpecificationAttrGroupItemModel>()
    val attrItemBinding = ItemBinding.of<SpecificationAttrGroupItemModel>(
        BR.specificationAttrGroupItemModel, R.layout.item_specification_attr_group
    )

    val closeClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        fragmentDialog.dismiss()
    })

    val minusClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        val oldQuantity = quantityObservableInt.get()
        val quantity = if (0 == stock) {
            0
        } else if (oldQuantity <= 1 || oldQuantity <= minPer) {
            if (1 < minPer) minPer else 1
        } else {
            oldQuantity - 1
        }
        quantityObservableInt.set(quantity)
    })

    val plusClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        val oldQuantity = quantityObservableInt.get()
        val quantity = if (oldQuantity >= stock || oldQuantity >= maxPer) {
            if (stock < maxPer) stock else maxPer
        } else {
            oldQuantity + 1
        }
        quantityObservableInt.set(quantity)
    })

    val confirmClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        fragmentDialog.onConfirmClickListener?.invoke(
            fragmentDialog.tag,
            selectedAttrIds(),
            selectedAttrNames(),
            quantityObservableInt.get().toString()
        )
        fragmentDialog.dismiss()
    })

    init {
        if (!fragmentDialog.selectedAttrIds.isNullOrEmpty()) {
            val oldAttrIds =
                fragmentDialog.selectedAttrIds!!.split(Constants.Extra.DECOLLATOR_DEFAULT)
            selectedAttrIds = arrayOfNulls(oldAttrIds.size)
            oldAttrIds.forEachIndexed { index, item ->
                selectedAttrIds!![index] = item
            }
            val oldAttrNames =
                fragmentDialog.selectedAttrNames!!.split(Constants.Extra.DECOLLATOR_DEFAULT)
            selectedAttrNames = arrayOfNulls(oldAttrNames.size)
            oldAttrNames.forEachIndexed { index, item ->
                selectedAttrNames!![index] = item
            }
        }
        val param = mutableMapOf<String, String?>()
        param["goods_id"] = fragmentDialog.goodsId
        fragmentDialog.requestData(
            Urls.Goods.GET_SPEC_GOODS_ATTR,
            param,
            GetSpecGoodsAttrData::class.java,
            {
                //显示规格
                attrItems.clear()
                it.list?.apply {
                    if (null == selectedAttrIds || selectedAttrIds?.size ?: 0 != size) {
                        selectedAttrIds = arrayOfNulls(size)
                        selectedAttrNames = arrayOfNulls(size)
                    }
                    forEachIndexed { index, item ->
                        if (!item.attr_values.isNullOrEmpty()) {
                            //记录选择的规格ID
                            if (selectedAttrIds!![index].isNullOrEmpty()) {
                                selectedAttrIds!![index] = item.attr_values[0].goods_attr_id
                                selectedAttrNames!![index] = item.attr_values[0].attr_value
                            }
                        }
                        attrItems += SpecificationAttrGroupItemModel(this@SpecificationModel, item)
                    }
                }
                //获取库存和价格
                getSku()
            })
    }

    fun getSku() {
        val params = mutableMapOf<String, String?>()
        params["goods_id"] = fragmentDialog.goodsId
        params["member_id"] = UserRepository.user.member_id
        params["goods_attr_ids"] = selectedAttrIds()
        fragmentDialog.requestData(Urls.Goods.GET_SKU, params, GetSkuData::class.java, {
            iconObservableField.set(it.cover_path)
            priceObservableField.set(showPrice(it.price))
            this@SpecificationModel._stock = it.stock.toInt()
            this@SpecificationModel._minPer = it.min_per.toInt()
            this@SpecificationModel._maxPer = it.max_per.toInt()
            quantityObservableInt.set(initializeQuantity(this.stock, this.minPer, this.minPer))
        })
    }

    private fun initializeQuantity(stock: Int, minPer: Int, maxPer: Int): Int {
        var currentQuantity = quantityObservableInt.get()
        currentQuantity = if (currentQuantity < stock || currentQuantity < minPer) {
            if (stock < minPer) stock else minPer
        } else if (currentQuantity > stock || currentQuantity > maxPer) {
            if (stock < maxPer) stock else maxPer
        } else {
            currentQuantity
        }
        return currentQuantity
    }

    private fun showPrice(sum: String?): CharSequence = when (fragmentDialog.goodsType) {
        Constants.Extra.COMMODITY_TYPE_INTEGRAL -> {
            val sum = if (sum.isNullOrEmpty()) "00" else sum
            SpannableStringBuilder("$sum${StringUtils.getString(R.string.str_integral)}").apply {
                setSpan(
                    RelativeSizeSpan(2f), 0, sum.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                setSpan(
                    StyleSpan(Typeface.BOLD), 0, sum.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
        }
        else -> {
            val sum = if (sum.isNullOrEmpty()) "0.00" else sum
            val symbol = StringUtils.getString(R.string.str_money_symbol)
            val unit = StringUtils.getString(R.string.str_money_unit)
            SpannableStringBuilder("$symbol$sum$unit").apply {
                setSpan(
                    RelativeSizeSpan(2f),
                    symbol.length,
                    sum.length + 1,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                setSpan(
                    StyleSpan(Typeface.BOLD),
                    symbol.length,
                    sum.length + 1,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
        }
    }

    /**
     * 选择的规格ID字符串
     *
     * @return
     */
    fun selectedAttrIds(): String {
        if (null == selectedAttrIds) return ""
        val result = StringBuilder()
        selectedAttrIds!!.forEach {
            val id = it ?: return@forEach
            if (result.isNotEmpty()) result.append(Constants.Extra.DECOLLATOR_DEFAULT)
            result.append(id)
        }
        return result.toString()
    }

    /**
     * 选择的规格名称字符串
     *
     * @return
     */
    fun selectedAttrNames(): String {
        if (null == selectedAttrNames) return ""
        val result = StringBuilder()
        selectedAttrNames!!.forEach {
            val id = it ?: return@forEach
            if (result.isNotEmpty()) result.append(Constants.Extra.DECOLLATOR_DEFAULT)
            result.append(id)
        }
        return result.toString()
    }

}